<?php
declare(strict_types=1);

namespace ExpressionEngine;

use ExpressionEngine\ExpressionEngine\Enum\ExpressionEnum;
use ExpressionEngine\LexicalAnalysisEngine\Enum\LexicalAnalysisEnum;
use ExpressionEngine\LoopEngine\LoopEngineInterface;

class ExpressionService
{
    protected ExpressionLogic $expressionLogic;
    protected LoopEngineInterface $loopEngine;

    public function __construct(ExpressionLogic $expressionLogic, LoopEngineInterface $loopEngine)
    {
        $this->expressionLogic = $expressionLogic;
        $this->loopEngine = $loopEngine;
    }

    protected function initializeCompileContext(): array
    {
        $compileContext = [];
        $compileContext[ExpressionEnum::COMPILE_ID_LOOP_LIST] = [];
        $compileContext[ExpressionEnum::COMPILE_ID_EXPRESSION_LIST] = [];
        $compileContext[ExpressionEnum::COMPILE_ID_VARIABLE_LIST] = [];
        $compileContext[ExpressionEnum::COMPILE_ID_CONSTANT_LIST] = [];
        return $compileContext;
    }

    /**
     * @param string $expression
     * @param array $context
     * @return mixed
     */
    public function compile(string $expression, array $context): mixed
    {
        $compileContext = $this->initializeCompileContext();
        $scanningData = $this->expressionLogic->getScanningData($expression);
        if (!empty($scanningData[LexicalAnalysisEnum::SCAN_KEY_LOOP_LIST_NAME])) {
            $compileContext[ExpressionEnum::COMPILE_ID_LOOP_LIST] = $this->loopEngine->compileList($scanningData[LexicalAnalysisEnum::SCAN_KEY_LOOP_LIST_NAME], $context, $compileContext);
        }
        return $this->expressionLogic->compile($scanningData, $context, $compileContext);
    }
}